package com.daoshu.socket.service.impl;

import com.corundumstudio.socketio.SocketIOClient;
import com.daoshu.socket.exception.SysException;
import com.daoshu.socket.redis.RedisUtil;
import com.daoshu.socket.view.PushMessageIn;
import com.daoshu.socket.bean.UserInfo;
import com.daoshu.socket.constants.Constants;
import com.daoshu.socket.service.ISendMessage;
import com.daoshu.socket.service.IUserService;
import com.daoshu.socket.service.SendMessageFactory;
import com.daoshu.socket.service.enums.SendTypeEnum;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * @ClassName: UserServiceImpl
 * @description:
 * @author: Allen
 * @create: 2019-06-24 21:21
 **/
@Service
@Slf4j
public class UserServiceImpl implements IUserService {


    @Autowired
    SendMessageFactory sendMessageFactory;

    @Autowired
    RedisUtil redisUtil;


    /***
     * 设置用户登录信息到内存MAP
     * @param client
     * @param userInfo
     */
    @Override
    public void setUserMapInfo(SocketIOClient client, UserInfo userInfo) {
        Lock lock = new ReentrantLock();
        lock.lock();
        try {

            //判断登录用户是否已经连接，如果已经连接将已存在的通道踢出
            List<UserInfo> userInfos = UserSessionManage.getUserInfoListByUserIds(Lists.newArrayList(userInfo.getUserId()));
            if (userInfos == null || userInfos.isEmpty()) {
                UserSessionManage.SESSIOIN_USERS.put(client.getSessionId().toString(), userInfo);
            } else {

                userInfos.forEach(userInfo1 -> {
                    if (userInfo1.getClient() != null && !client.getSessionId().toString().equalsIgnoreCase(userInfo1.getClient().getSessionId().toString())) {
                        removeUserMapInfo(userInfo1.getClient());
                        userInfo1.getClient().disconnect();
                    }
                });

                UserSessionManage.SESSIOIN_USERS.put(client.getSessionId().toString(), userInfo);
            }

        } finally {
            lock.unlock();
        }
        try {
            //redisUtil.lSet(Constants.USER_TOKEN, client.getSessionId().toString());
        } catch (Exception e) {
            log.error("setUserMapInfo err:" + e.getMessage());
        }
    }

    /***
     * 移除MAP 对应数据
     * @param client
     */
    @Override
    public void removeUserMapInfo(SocketIOClient client) {
        Lock lock = new ReentrantLock();
        lock.lock();
        try {
            UserSessionManage.SESSIOIN_USERS.remove(client.getSessionId().toString());
            client.disconnect();
            try {
                //redisUtil.lRemove(Constants.USER_TOKEN, 0, client.getSessionId().toString());
            } catch (Exception e) {
                log.error("setUserMapInfo err:" + e.getMessage());
            }
        } finally {
            lock.unlock();
        }
    }

    /***
     * 给用户发送消息
     * @param in
     */
    @Override
    public void sendMessageForUser(PushMessageIn in) {

        if (in == null) {
            log.info("sendMessageForUser in is null");
            return;
        }

        if (in.getTo() == null || in.getTo().isEmpty()) {
            throw new SysException("发送指定用户列表参数错误");
        }

        String sendType;
        if (in.getTo().contains("*")) {
            sendType = SendTypeEnum.USER_ALL.getType();
        } else {
            sendType = SendTypeEnum.USER_IDS.getType();
        }

        ISendMessage sendMessage = sendMessageFactory.getInstance(sendType);
        if (sendMessage != null) {
            if (in.getGroupId() != null && !in.getGroupId().isEmpty()) {
                sendMessage.sendMessageByGroup(in);
            } else {
                sendMessage.sendMessage(in);
            }
        }
    }


}
